package com.cpi.cornpp.creditlinebalance.action;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.Globals;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.MappingDispatchAction;
import org.apache.struts.util.MessageResources;

import com.cpi.cornpp.creditline.services.CreditLineService;
import com.cpi.cornpp.creditline.view.CreditLineView;
import com.cpi.cornpp.creditlinebalance.dto.CreditLineBalanceRecentDTO;
import com.cpi.cornpp.creditlinebalance.form.CreditLineBalanceForm;
import com.cpi.cornpp.creditlinebalance.services.CreditLineBalanceService;
import com.cpi.cornpp.creditlinebalance.view.CreditLineBalanceView;
import com.cpi.cornpp.monthsperiods.services.MonthsPeriodsService;
import com.cpi.cornpp.monthsperiods.view.MonthsPeriodsView;
import com.cs.common.init.SystemParameterCollection;
import com.cs.common.utils.StringUtils;

public class CreditLineBalanceAction extends MappingDispatchAction{
	
	private static final String LINE_CREDIT_MONTHS_BEFORE = "LINE_CREDIT_MONTHS_BEFORE";
	private static final String LINE_CREDIT_MONTHS_AHEAD = "LINE_CREDIT_MONTHS_AHEAD";
	private String MSG_BALANCES_UPDATED = "label.creditlinebalance.records.updated";
	private String MESSAGE = "MESSAGE";
	private String CLB_RECENTS = "CLB_RECENTS";

	public ActionForward go(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		MonthsPeriodsService monthsPeriodService = null;
		List periods = null;
		CreditLineService creditLineService = null;
		CreditLineBalanceForm form = null;
		CreditLineView creditLineView = null;
		CreditLineBalanceService service = null;
		int thisMonth = 0;
		int monthsBefore = 0;
		int monthsAhead = 0;
		int actualMonth = 0;
		double difference = 0.0;
		
		List subListPeriods = null;	
		List balances = null;
		service = new CreditLineBalanceService();
		
		monthsBefore = SystemParameterCollection.getInstance().getSystemParameterBean(LINE_CREDIT_MONTHS_BEFORE).getIntValue();
		monthsAhead = SystemParameterCollection.getInstance().getSystemParameterBean(LINE_CREDIT_MONTHS_AHEAD).getIntValue();
					
		monthsPeriodService = new MonthsPeriodsService();				
		periods = monthsPeriodService.listOfMonthsPeriods();
		creditLineService = new CreditLineService();
		creditLineView = creditLineService.getCredtiLineDTO();				
		
		actualMonth = monthsPeriodService.actualMonthPeriod();
		thisMonth = getIndexMonth( actualMonth, periods );
		
		if( thisMonth - monthsBefore > thisMonth + monthsAhead){
			subListPeriods = periods.subList(thisMonth - monthsBefore, thisMonth - monthsBefore);
		}else{
			subListPeriods = periods.subList(thisMonth - monthsBefore, thisMonth + (monthsAhead+1));
		}
				
		form = (CreditLineBalanceForm)actionForm;
		
		form.setListPeriods(periods);		
		form.setSubListPeriods(subListPeriods);
		form.setView(creditLineView);		
		form.setInitPeriodId(actualMonth - monthsBefore);
		form.setFinishPeriodId(actualMonth + monthsAhead);
		
		form.setSubInitPeriodId(actualMonth - monthsBefore);
		form.setSubFinishPeriodId(actualMonth - monthsBefore);
		
		balances = service.list(form.getView().getCreditLineId(), form.getInitPeriodId(), form.getFinishPeriodId());
		Iterator iterator = balances.iterator();
		difference = form.getView().getExceededLimit() - form.getView().getLimit();
		while(iterator.hasNext()){
			CreditLineBalanceView cv = (CreditLineBalanceView)iterator.next();
			cv.setAvailable(form.getView().getLimit() - cv.getBalance());
			cv.setNewBalance(cv.getBalance());
			if(cv.getAvailable() < 0 && Math.abs(cv.getAvailable()) < difference ){
				cv.setOverDrawn(CreditLineBalanceView.OVERDRAWN_CREDIT);
			}else if(cv.getAvailable() < 0 && Math.abs(cv.getAvailable()) > difference){
				cv.setOverDrawn(CreditLineBalanceView.OVERDRAWN_LIMIT);
			}else {
				cv.setOverDrawn(StringUtils.EMPTY_STRING);
			}
		}
		form.setBalances(balances);
		form.setPre(false);
		form.setAmount(0);
		return mapping.findForward("default");
	}
	
	private int getIndexMonth(int actualMonthPeriod, List periods) {
		int monthIndex = -1;
		ListIterator iterator = null;
		MonthsPeriodsView monthsPeriodsView = null;
		iterator = periods.listIterator();
		while( iterator.hasNext() ){
			monthsPeriodsView = (MonthsPeriodsView)iterator.next();
			if( monthsPeriodsView.getMonthPeriodId() == actualMonthPeriod ){
				monthIndex = iterator.previousIndex();
				break;
			}
		}
		return monthIndex;
	}

	public ActionForward buildPeriods(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		CreditLineBalanceForm form = null;
		CreditLineBalanceService service = null;
		int initId = 0;
		int finishId = 0;
		double difference = 0.0;
		
		List subListPeriods = null;		
		List balances = null; 
		form = (CreditLineBalanceForm)actionForm;
		service = new CreditLineBalanceService();
		balances = service.list(form.getView().getCreditLineId(), form.getInitPeriodId(), form.getFinishPeriodId());
		
		initId = form.getListPeriods().indexOf(new MonthsPeriodsView(form.getInitPeriodId()));
		finishId = form.getListPeriods().indexOf(new MonthsPeriodsView(form.getFinishPeriodId()));
		if( initId > finishId + 1 ){
			subListPeriods = form.getListPeriods().subList(initId, initId);
		}else{
			subListPeriods = form.getListPeriods().subList(initId, finishId + 1);
		}
		difference = form.getView().getExceededLimit() - form.getView().getLimit();
		Iterator iterator = balances.iterator();
		while(iterator.hasNext()){
			CreditLineBalanceView cv = (CreditLineBalanceView)iterator.next();
			cv.setAvailable(form.getView().getLimit() - cv.getBalance());
			cv.setNewBalance(cv.getBalance());
			if(cv.getAvailable() < 0 && Math.abs(cv.getAvailable()) < difference ){
				cv.setOverDrawn(CreditLineBalanceView.OVERDRAWN_CREDIT);
			}else if(cv.getAvailable() < 0 && Math.abs(cv.getAvailable()) > difference){
				cv.setOverDrawn(CreditLineBalanceView.OVERDRAWN_LIMIT);
			}else {
				cv.setOverDrawn(StringUtils.EMPTY_STRING);
			}
		}
		form.setBalances(balances);
		form.setSubListPeriods(subListPeriods);
		form.setSubInitPeriodId(initId);
		form.setSubFinishPeriodId(initId);
		form.setPre(false);
		//falta resetear los subperiodos
		return mapping.findForward("default");
		
	}
	
	public ActionForward applyAmountToPeriods(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		CreditLineBalanceForm form = null;
		int subInitId = 0;
		int subFinishId = 0;
		List subPeriods = null;
		List balances = null;
		List balancesApplied;
		double difference = 0.0;
		
		form = (CreditLineBalanceForm)actionForm;
		form.setPre(true);
		subPeriods = form.getSubListPeriods();
		balances = form.getBalances();
		subInitId = subPeriods.indexOf(new MonthsPeriodsView(form.getSubInitPeriodId()));
		subFinishId = subPeriods.indexOf(new MonthsPeriodsView(form.getSubFinishPeriodId()));
		if( subInitId > subFinishId+1 ){
			balancesApplied = form.getBalances().subList(subInitId, subInitId);
		}else{
			balancesApplied = form.getBalances().subList(subInitId, subFinishId+1);
		}
		form.setBalancesApplied(balancesApplied);
		Iterator it1 = balances.iterator();
		difference = form.getView().getExceededLimit() - form.getView().getLimit();
		
		while(it1.hasNext()){
			CreditLineBalanceView cv = (CreditLineBalanceView)it1.next();			
			if(balancesApplied.contains(cv)){				
				cv.setAvailable(form.getView().getLimit() - (cv.getBalance() + form.getAmount()));
				cv.setNewBalance(cv.getBalance() + form.getAmount());
				cv.setMonthlyPeriodApplied(true);
			}else{
				cv.setAvailable(form.getView().getLimit() - cv.getBalance());
				cv.setNewBalance(cv.getBalance());
				cv.setOverDrawn(StringUtils.EMPTY_STRING);
				cv.setMonthlyPeriodApplied(false);
			}
			
			if(cv.getAvailable() < 0 && Math.abs(cv.getAvailable()) < difference ){
				cv.setOverDrawn(CreditLineBalanceView.OVERDRAWN_CREDIT);
			}else if(cv.getAvailable() < 0 && Math.abs(cv.getAvailable()) > difference){
				cv.setOverDrawn(CreditLineBalanceView.OVERDRAWN_LIMIT);
			}else {
				cv.setOverDrawn(StringUtils.EMPTY_STRING);
			}
		}
		
		return mapping.findForward("default");
	}
	
	public ActionForward updateBalances(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		CreditLineBalanceService service = null;
		CreditLineBalanceForm form = null;
		List balancesApplied = null;
		MessageResources messages = null;
		messages = getResources(request);
		HttpSession httpSession = null; 
		ArrayList clbRecents = null;
		CreditLineBalanceRecentDTO clbRecent = null;
		
		int subInitId = 0;
		int subFinishId = 0;
		List subPeriods = null;
		MonthsPeriodsView mview = null;
		StringBuffer label = new StringBuffer(0);		

		httpSession = request.getSession();
		service = new CreditLineBalanceService();
		form = (CreditLineBalanceForm)actionForm;
		subPeriods = form.getSubListPeriods();
		balancesApplied = form.getBalancesApplied();
		service.update(balancesApplied);
		
		clbRecent = new CreditLineBalanceRecentDTO();
		subInitId = subPeriods.indexOf(new MonthsPeriodsView(form.getSubInitPeriodId()));
		subFinishId = subPeriods.indexOf(new MonthsPeriodsView(form.getSubFinishPeriodId()));
		mview = (MonthsPeriodsView)subPeriods.get(subInitId);		
		label.append(mview.getLabel());
		mview = (MonthsPeriodsView)subPeriods.get(subFinishId);
		label.append(StringUtils.SPACE_CHAR);
		label.append(StringUtils.SLASH_CHAR);
		label.append(StringUtils.SPACE_CHAR);
		label.append(mview.getLabel());

		
		clbRecent.setDate(Calendar.getInstance().getTime());	
		clbRecent.setRangePeriod(label.toString());		
		clbRecent.setAmount(String.valueOf(form.getAmount()));
		
		clbRecents = (ArrayList)request.getSession(false).getAttribute("CLB_RECENTS");
		if(clbRecents!=null){
			clbRecents.add(clbRecent);
		}else{
			clbRecents = new ArrayList();
			clbRecents.add(clbRecent);
			request.getSession(false).setAttribute(CLB_RECENTS  , clbRecents);
		}
		
		//request.getSession(false).setAttribute(CLB_RECENTS  , clbRecents);
		messages.getMessage((Locale)httpSession.getAttribute(Globals.LOCALE_KEY), MSG_BALANCES_UPDATED);
		request.getSession(false).setAttribute(MESSAGE , messages.getMessage(MSG_BALANCES_UPDATED));
		form.setAmount(0);
		return mapping.findForward("default");
	}

}
